﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Csla.DataPortalClient;
using Csla.Server;
using Csla.Server.Hosts;
using Csla.Server.Hosts.WcfChannel;

using Microsoft.SharePoint;

namespace SPaDevToolkit.Administration
{
    public class SPaCslaWcfProxy : IDataPortalProxy
    {
        #region IDataPortalProxy Members

        public bool IsServerRemote
        {
            get { return true; }
        }

        public DataPortalResult Create(Type objectType, object criteria, DataPortalContext context)
        {
            IWcfPortal portal = GetWcfPortal(objectType);
            WcfResponse response = null;

            try
            {
                response = portal.Create(new CreateRequest(objectType, criteria, context));
            }
            catch (Exception ex)
            {
                throw;
            }

            object result = response.Result;
            if (result is Exception)
                throw (Exception)result;
            return (DataPortalResult)result;
        }

        public DataPortalResult Delete(Type objectType, object criteria, DataPortalContext context)
        {
            IWcfPortal portal = GetWcfPortal(objectType);
            WcfResponse response = null;

            try
            {
                response = portal.Delete(new DeleteRequest(objectType, criteria, context));
            }
            catch (Exception ex)
            {
                throw;
            }

            object result = response.Result;
            if (result is Exception)
                throw (Exception)result;
            return (DataPortalResult)result;
        }

        public DataPortalResult Fetch(Type objectType, object criteria, DataPortalContext context)
        {
            IWcfPortal portal = GetWcfPortal(objectType);
            WcfResponse response = null;

            try
            {
                response = portal.Fetch(new FetchRequest(objectType, criteria, context));
            }
            catch (Exception ex)
            {
                throw;
            }

            object result = response.Result;
            if (result is Exception)
                throw (Exception)result;
            return (DataPortalResult)result;

        }

        public DataPortalResult Update(object obj, DataPortalContext context)
        {
            IWcfPortal portal = GetWcfPortal(obj.GetType());
            WcfResponse response = null;

            try
            {
                response = portal.Update(new UpdateRequest(obj, context));
            }
            catch (Exception ex)
            {
                throw;
            }

            object result = response.Result;
            if (result is Exception)
                throw (Exception)result;
            return (DataPortalResult)result;
        }

        private static IWcfPortal GetWcfPortal(Type objectType)
        {
            SPaWebServiceApplicationProxyAttribute proxyAttribute = Attribute.GetCustomAttribute(objectType.Assembly, typeof(SPaWebServiceApplicationProxyAttribute)) as SPaWebServiceApplicationProxyAttribute;
            IWcfPortal portal = SPServiceContext.Current.GetDefaultProxy(proxyAttribute.ProxyType) as IWcfPortal;
            if (portal == null)
                throw new InvalidOperationException(string.Format("Service Application Proxy of type {0} not found", proxyAttribute.ProxyType.AssemblyQualifiedName));
            return portal;
        }

        #endregion
    }
}
